'''
Created on Mar 18, 2010

@author: Andrzej
'''
from PyDaq.Hardware.Avr import AvrShell
from PyDaq.Utils.Debug import dbg

import time
import re
_ip_addr = re.compile('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')

class Daq328p(AvrShell):
    '''
    classdocs
    '''        
    
    _OFF     = 0
    _ON      = 1
    debug    = 0
    idn      = ''
    dev      = 0
    location = ''
    rom      = []

    def __init__(self, host='COM', port=7):
        dbg(self, 1, 'def: __init__(self)')
        
        #print host
        if len(_ip_addr.findall(str(host))) == 1:
            #print "Address is IP"
            port = 2000;
        else:
            #print "Address is COM"
            port = host
            host = 'COM'             
            
        AvrShell.__init__(self, host, port)
        self.open()
        time.sleep(0.25)
        if self.prompt():
            pass
            #self.GetIdn()
            #self.GetDevInfo()
            #self.GetRom()
        else:
            print "Did not find command prompt!"
        
    def __del__(self):
        ''' 
        Destructor        
        '''
        dbg(self, 1, 'def: __del__(self)')
        self.close()
        
    def __unicode__(self):
        return "Daq328p"
    
    def GetDevInfo(self):
        dev = self.ParseCommand('N','','dev')
        if len(dev)>0 and len(dev[0])==2:
            self.location = dev[0][0]
            self.dev      = dev[0][1]
        else:
            dev = [['', '']]
        return dev 
    
    def GetIdn(self):
        idn      = self.ParseCommand('I','idn')
        self.idn = idn        
        return idn
    
    def GetRom(self):
        raw = self.ParseCommand('L','ROM','R')        
        rom = []
        for i in raw:
            tmp_rom = i[1].strip()
            tmp_rom = tmp_rom.replace("   ", " ")
            tmp_rom = tmp_rom.replace("  ",  " ")            
            rom.append(tmp_rom)
        self.rom = rom
        return rom
    
    def GetADC(self, volt=1): 
        dbg(self, 1, 'def GetADC(self)')        
        
        raw  = self.ParseCommand('A','ADC','A')
        adc  = [] 
        for i in raw:
            val  = int(i[1])
            if volt==1:
                dbg(self,2,'Converting to voltage: {0} = {1}V'.format(i[1],val))                
                val = float(val*5)/1024
            adc.append([i[0], val])
        return adc
    
    def GetDI(self):
        dbg(self, 1, 'def GetDI(self)')        
        raw = self.ParseCommand('D','DIO','D')
        dio = []        
        for i in raw:
            dio.append([i[0], int(i[1])])
        return dio
    
    def GetThermocoupleReading(self):
        out = self.query("test", expected_text="</t>", tag="t")
        return str2num(out)
    
    def GetTemperature(self):
        dbg(self, 1, 'def GetTemperature(self)')
        raw  = self.ParseCommand('T','temp','T')
        temp = []        
        for i in raw:
            if not 'CRC ERROR' in i[1]:
                sn = i[0].strip()
                sn = sn.replace("   ", " ")
                sn = sn.replace("  ",  " ") 
                temp.append([sn, float(i[1])])
            else:
                dbg(self,0,'CRC Error on sensor: {0}'.format(i[0]))                                
        return temp
    
    def GetData(self, cmd, delay, attempt=1):
        pass
    
    def ParseCommand(self, cmd, tag1='',tag2=''):
        dbg(self,1,'def ParseCommand(self, {0}, tag1={1}, tag2={2}):'.format(cmd,tag1,tag2))
        raw       = self.query(cmd,tag=tag1)        
        pattern   = re.compile(r'(?:<{0} \w+=")(.*)(?:">)(.*)(?:</{0}>)'.format(tag2))
                
        if len(tag2) > 0:            
            out  = pattern.findall(raw)
            if len(out) > 0:
                dbg(self,2,"Recovered tag2: {0}".format(tag2))             
                return out
            else:
                dbg(self,2,"Did not recovered tag2: {0}".format(tag2))
                return ''    
        else:
            return raw
    def Test(self):
        pass
        
def str2num(str):
    out = [float(x) for x in str.split()]
    return out

if __name__ == '__main__':
    print "================================"
    print "HomeSensors module test function"
    #dev_list = {1:['COM',7],2:['192.168.1.100',2000],3:['COM',3],4:['COM',4]}
    #dev_num = int(raw_input("Please enter device number: "))
    num_of_readings = int(raw_input("Please enter number of readings to acquire: "))
    #dev  = dev_list.get(dev_num)    
    D    = Daq328p(7)
    
    test1 = 1
    test2 = 0
    
    if test1:
        print D.GetDI()
        print D.GetADC()
        print D.GetTemperature()
        print D.GetIdn()
        print D.GetDevInfo()
        print D.GetRom()
    elif test2:
        D.debug = 0
        D.open()
        for itter in range(num_of_readings):
            t = time.gmtime()
            
            temp = D.GetTemperature()
            adc  = D.GetADC(volt=0)
            dio  = D.GetDI()        
            str  = '' 
            str = 'Temp: '           
            for ii in temp:
                str += "{0:.1f}, ".format(ii[1])                   
            str+= '  ADC: '
            for ii in adc:
                V = float(ii[1]*5)/1024
                str += "{0}, {1:.2f}V".format( ii[1], V )                
            str+= '  DIO: '
            for ii in dio:
                str += "{0},".format(ii[1])                
            print itter, ", %d.%d.%d %d:%d:%d, " % t[0:6], D.location, str
    D.close()
    del(D)
    print "ALL DONE"